﻿using _RobotInspection.DTO;
using _RobotInspection.Entities;
using _RobotInspection.Interfaces;
using _RobotInspection.Models;
using SqlSugar;
using System.Text;
using static System.Net.WebRequestMethods;

namespace _RobotInspection.Services
{
    /// <summary>
    /// 维修计划相关服务层实现类
    /// </summary>
    public class RepairPlanService : IRepairPlanService
    {
        private readonly ISqlSugarClient _db;
        private readonly ILogger<RepairPlanService> _logger;
        private readonly IConfiguration _config;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        /// <param name="logger"></param>
        /// <param name="config"></param>
        public RepairPlanService(ISqlSugarClient db, ILogger<RepairPlanService> logger, IConfiguration config)
        {
            _db = db;
            _logger = logger;
            _config = config;
        }

        /// <summary>
        /// 异步分页查询维修计划
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<RepairPlanPagedResultDto>> GetRepairPlansPagedAsync(RepairPlanPagedDto queryDto)
        {
            try
            {
                // 联表查询
                var queryable = _db.Queryable<repair_plan>()
                    .LeftJoin<inspection_records>((rp, ir) => rp.record_id == ir.id)
                    .LeftJoin<inspection_items>((rp, ir, ii) => ir.item_id == ii.id)
                    .LeftJoin<equipment>((rp, ir, ii, e) => ii.equipment_id == e.id)
                    .LeftJoin<users>((rp, ir, ii, e, u) => rp.user_id == u.id);

                // 按要求添加查询条件
                if (!string.IsNullOrWhiteSpace(queryDto.Unit))
                {
                    queryable = queryable.Where((rp, ir, ii, e, u) => e.unit.Contains(queryDto.Unit));
                }
                if (!string.IsNullOrWhiteSpace(queryDto.EquipmentName))
                {
                    queryable = queryable.Where((rp, ir, ii, e, u) => e.equipment_name.Contains(queryDto.EquipmentName));
                }
                if (queryDto.UserId.HasValue)
                {
                    queryable = queryable.Where((rp, ir, ii, e, u) => u.id == queryDto.UserId);
                }
                if (!string.IsNullOrWhiteSpace(queryDto.PlanName))
                {
                    queryable = queryable.Where((rp, ir, ii, e, u) => rp.plan_name.Contains(queryDto.PlanName));
                }
                if (queryDto.Status.HasValue)
                {
                    queryable = queryable.Where((rp, ir, ii, e, u) => rp.status == queryDto.Status);
                }

                // 获取总记录数
                var totalCount = await queryable.CountAsync();

                // 准备返回数据
                var repairPlanResultDtoList = await queryable.Select((rp, ir, ii, e, u) => new RepairPlanResultDto
                {
                    Id = rp.id,
                    Unit = e.unit,
                    EquipmentName = e.equipment_name,
                    PlanName = rp.plan_name,
                    RepairmanRealName = u.real_name,
                    Remark = rp.remark,
                    Status = rp.status,
                    BeginningTime = rp.beginning_time,
                    EndingTime = rp.ending_time,
                    PicturePath = rp.picture_path,
                    CreatedAt = rp.created_at,
                    UpdatedAt = rp.updated_at
                })
                .ToPageListAsync(queryDto.PageIndex, queryDto.PageSize);

                // 图片路径从数据库中的相对路径变换为url绝对路径
                foreach (var repairPlanResultDto in repairPlanResultDtoList)
                {
                    repairPlanResultDto.PicturePath = Path.Combine(_config["Urls"] ?? "", repairPlanResultDto.PicturePath ?? "");
                }

                //判断总页数
                var totalPages = 0;
                if (totalCount % queryDto.PageSize > 0)
                {
                    totalPages = totalCount / queryDto.PageSize + 1;
                }
                else
                {
                    totalPages = totalCount / queryDto.PageSize;
                }

                //准备分页返回数据
                var repairPlanPagedResultDto = new RepairPlanPagedResultDto
                {
                    RepairPlanResultList = repairPlanResultDtoList,
                    TotalCount = totalCount,
                    TotalPages = totalPages,
                    CurrentPage = queryDto.PageIndex,
                    PageSize = queryDto.PageSize,
                    HasPreviousPage = queryDto.PageIndex > 1,
                    HasNextPage = queryDto.PageIndex < totalPages
                };

                var message = $"查询到维修计划总数：{totalCount}";

                return ApiResponse<RepairPlanPagedResultDto>.Success(repairPlanPagedResultDto, message, totalCount);
            }
            catch (Exception ex)
            {
                return ApiResponse<RepairPlanPagedResultDto>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按ID查询维修计划
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<repair_plan>> GetRepairPlanByIdAsync(long id)
        {
            // 检验数据是否合法
            if (id <= 0)
            {
                return ApiResponse<repair_plan>.Error("查询失败：维修计划ID无效", 400);
            }

            try
            {
                // 检验数据是否存在
                var repairPlanList = await _db.Queryable<repair_plan>().Where(rp => rp.id == id).ToListAsync();
                if (repairPlanList.Count == 1)
                {
                    // 联表查询
                    var repairPlan = await _db.Queryable<repair_plan>() .Where(rp => rp.id == id).FirstAsync();

                    return ApiResponse<repair_plan>.Success(repairPlan, null);
                }
                else
                {
                    return ApiResponse<repair_plan>.Error("查询失败：维修计划不存在", 400);
                }
            }
            catch (Exception ex)
            {
                return ApiResponse<repair_plan>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步创建维修计划
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<repair_plan>> InsertRepairPlanAsync(RepairPlanDto queryDto)
        {
            // 检验数据是否合法
            if (queryDto.RecordId <= 0)
            {
                return ApiResponse<repair_plan>.Error("维修计划创建失败：点检记录ID不合法", 400);
            }
            if (queryDto.UserId <= 0)
            {
                return ApiResponse<repair_plan>.Error("维修计划创建失败：维修人员ID不合法", 400);
            }
            if (string.IsNullOrWhiteSpace(queryDto.PlanName))
            {
                return ApiResponse<repair_plan>.Error("维修计划创建失败：需要维修计划名称", 400);
            }

            try
            {
                // 检验外键是否存在
                var inspectionRecordNumber = await _db.Queryable<inspection_records>().Where(ir => ir.id == queryDto.RecordId).CountAsync();
                if (inspectionRecordNumber != 1)
                {
                    return ApiResponse<repair_plan>.Error("维修计划创建失败：点检记录不存在", 400);
                }
                var userNumber = await _db.Queryable<users>().Where(u => u.id == queryDto.UserId).CountAsync();
                if (userNumber != 1)
                {
                    return ApiResponse<repair_plan>.Error("维修计划创建失败：维修人员不存在", 400);
                }

                // 判断维修计划状态
                byte status = 0;
                if (DateTime.Now < queryDto.BeginningTime || queryDto.BeginningTime == null)
                {
                    status = 0; // 检修未开始
                }
                else if (queryDto.BeginningTime <= DateTime.Now && DateTime.Now <= queryDto.EndingTime || queryDto.EndingTime == null)
                {
                    status = 1; // 带待检修
                }
                else
                {
                    status = 4; // 检修逾期
                }

                // 准备维修计划数据
                var repairPlan = new repair_plan
                {
                    record_id = queryDto.RecordId,
                    user_id = queryDto.UserId,
                    plan_name = queryDto.PlanName,
                    remark = queryDto.Remark,
                    status = status,
                    beginning_time = queryDto.BeginningTime,
                    ending_time = queryDto.EndingTime,
                    created_at = DateTime.Now,
                    updated_at = DateTime.Now
                };

                // 插入关注事项数据
                var repairPlanResult = await _db.Insertable(repairPlan).ExecuteReturnEntityAsync();

                return ApiResponse<repair_plan>.Success(repairPlanResult, "维修计划创建成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<repair_plan>.Error($"维修计划创建失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改维修计划
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<repair_plan>> UpdateRepairPlanAsync(RepairPlanUpdateDto queryDto)
        {
            // 检验数据是否合法
            if (queryDto.Id <= 0)
            {
                return ApiResponse<repair_plan>.Error("维修计划修改失败：维修计划ID不合法", 400);
            }
            if (queryDto.UserId.HasValue)
            {
                if(queryDto.UserId <= 0)
                {
                    return ApiResponse<repair_plan>.Error("维修计划修改失败：维修人员ID不合法", 400);
                }
            }
            if (queryDto.Status.HasValue)
            {
                if (queryDto.Status != 2 || queryDto.Status != 3 || queryDto.Status != 5) 
                {
                    return ApiResponse<repair_plan>.Error("维修计划修改失败：维修状态不合法，必须是2-检修完成或3-检修待跟进或5-检修取消", 400);
                }
            }

            try
            {
                // 检验维修计划是否存在
                var repairPlanList = await _db.Queryable<repair_plan>().Where(rp => rp.id == queryDto.Id).ToListAsync();
                if (repairPlanList.Count != 1)
                {
                    return ApiResponse<repair_plan>.Error("维修计划修改失败：维修计划不存在", 400);
                }

                var userList = new List<users> { };
                if (queryDto.UserId.HasValue)
                {
                    userList = await _db.Queryable<users>().Where(u => u.id == queryDto.UserId).ToListAsync();
                    if(userList.Count != 1)
                    {
                        return ApiResponse<repair_plan>.Error("维修计划修改失败：维修人员不存在", 400);
                    }
                }

                // 保存文件的准备工作
                string indirectSaveDir = "RepairPlanPicture";
                string directSaveDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", indirectSaveDir);
                if (!Directory.Exists(directSaveDir))
                {
                    Directory.CreateDirectory(directSaveDir);
                }


                // 保存图片文件
                string? indirectSavePath = null;
                string? directSavePath = null;
                if (queryDto.Picture != null) 
                {
                    string mimeType = queryDto.Picture.ContentType;
                    if (!mimeType.StartsWith("image/"))
                    {
                        return ApiResponse<repair_plan>.Error("维修计划修改失败：文件类型不是图片", 400);
                    }

                    // 如果已经有图片文件，删除
                    if (System.IO.File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", repairPlanList[0].picture_path ?? "")))
                    {
                        System.IO.File.Delete(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", repairPlanList[0].picture_path ?? ""));
                    }

                    string fileName = $"{Guid.NewGuid()}_{Path.GetFileName(queryDto.Picture.FileName)}";
                    indirectSavePath = Path.Combine(indirectSaveDir, fileName);
                    directSavePath = Path.Combine(directSaveDir, fileName);
                    using (var stream = new FileStream(directSavePath, FileMode.Create))
                    {
                        await queryDto.Picture.CopyToAsync(stream);
                    }
                }

                byte status = repairPlanList[0].status ?? 0;
                if (queryDto.Status == null && (repairPlanList[0].status == 0 || repairPlanList[0].status == 1))
                {
                    // 判断维修计划状态
                    if (DateTime.Now < repairPlanList[0].beginning_time || repairPlanList[0].beginning_time == null)
                    {
                        status = 0; // 检修未开始
                    }
                    else if (repairPlanList[0].beginning_time <= DateTime.Now && DateTime.Now <= repairPlanList[0].ending_time || repairPlanList[0].ending_time == null)
                    {
                        status = 1; // 带待检修
                    }
                    else
                    {
                        status = 4; // 检修逾期
                    }
                }

                // 准备修改数据
                var repairPlan = new repair_plan() 
                {
                    id = repairPlanList[0].id,
                    record_id = repairPlanList[0].record_id,
                    user_id = queryDto.UserId ?? repairPlanList[0].user_id,
                    plan_name = queryDto.PlanName ?? repairPlanList[0].plan_name,
                    status = queryDto.Status ?? status,
                    remark = queryDto.Remark ?? repairPlanList[0].remark,
                    beginning_time = repairPlanList[0].beginning_time,
                    ending_time = repairPlanList[0].ending_time,
                    picture_path = indirectSavePath ?? repairPlanList[0].picture_path,
                    created_at = repairPlanList[0].created_at,
                    updated_at = DateTime.Now
                };

                var repairPlanResult = await _db.Updateable(repairPlan).ExecuteReturnEntityAsync();
                return ApiResponse<repair_plan>.Success(repairPlanResult, "维修计划修改成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<repair_plan>.Error($"维修计划修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步删除维修计划
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<repair_plan?>> DeleteRepairPlanAsyc(long id)
        {
            // 检验数据是否合法
            if (id <= 0)
            {
                return ApiResponse<repair_plan?>.Error("维修计划删除失败：维修计划ID不合法", 400);
            }

            try
            {
                // 检验数据是否存在
                var repairPlanList = await _db.Queryable<repair_plan>().Where(rp => rp.id == id).ToListAsync();
                if (repairPlanList.Count != 1)
                {
                    return ApiResponse<repair_plan?>.Error("维修计划删除失败：维修计划不存在", 400);
                }

                // 删除本地文件
                if (System.IO.File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", repairPlanList[0].picture_path ?? "")))
                {
                    System.IO.File.Delete(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", repairPlanList[0].picture_path ?? ""));
                }

                await _db.Deleteable<repair_plan>().Where(rp => rp.id == id).ExecuteCommandAsync();
                return ApiResponse<repair_plan?>.Success(null, "维修计划删除成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<repair_plan?>.Error($"维修计划删除失败：{ex.Message}", 500);
            }
        }
    }
}
